<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge" >
  <title>程序员为什么热衷造轮子 | Grx Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="程序员为什么热衷造轮子 搜索一下“造轮子”或者“程序员为什么喜欢造轮子”，会看到很多相关的讨论，这是个老生常谈的话题，很多人谈过了，谈了很多年。不过还是有再谈的必要。">
<meta property="og:type" content="article">
<meta property="og:title" content="程序员为什么热衷造轮子">
<meta property="og:url" content="http://yoursite.com/2015/08/17/程序员为什么热衷造轮子/index.html">
<meta property="og:site_name" content="Grx Blog">
<meta property="og:description" content="程序员为什么热衷造轮子 搜索一下“造轮子”或者“程序员为什么喜欢造轮子”，会看到很多相关的讨论，这是个老生常谈的话题，很多人谈过了，谈了很多年。不过还是有再谈的必要。">
<meta property="og:updated_time" content="2016-05-18T09:15:36.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="程序员为什么热衷造轮子">
<meta name="twitter:description" content="程序员为什么热衷造轮子 搜索一下“造轮子”或者“程序员为什么喜欢造轮子”，会看到很多相关的讨论，这是个老生常谈的话题，很多人谈过了，谈了很多年。不过还是有再谈的必要。">
  
    <link rel="alternative" href="/atom.xml" title="Grx Blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  <link rel="stylesheet" href="/css/style.css">
</head>

<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
	<header id="header" class="inner">
		<a href="/" class="profilepic">
			
			<img lazy-src="/img/rufei.jpg" class="js-avatar">
			
		</a>

		<hgroup>
		  <h1 class="header-author"><a href="/">Grx</a></h1>
		</hgroup>

		
		<p class="header-subtitle">自我管理，知识管理，时间管理，阅读，语音写作，思维导图</p>
		

		
			<div class="switch-btn">
				<div class="icon">
					<div class="icon-ctn">
						<div class="icon-wrap icon-house" data-idx="0">
							<div class="birdhouse"></div>
							<div class="birdhouse_holes"></div>
						</div>
						<div class="icon-wrap icon-ribbon hide" data-idx="1">
							<div class="ribbon"></div>
						</div>
						
						<div class="icon-wrap icon-link hide" data-idx="2">
							<div class="loopback_l"></div>
							<div class="loopback_r"></div>
						</div>
						
						
						<div class="icon-wrap icon-me hide" data-idx="3">
							<div class="user"></div>
							<div class="shoulder"></div>
						</div>
						
					</div>
					
				</div>
				<div class="tips-box hide">
					<div class="tips-arrow"></div>
					<ul class="tips-inner">
						<li>菜单</li>
						<li>标签</li>
						
						<li>友情链接</li>
						
						
						<li>关于我</li>
						
					</ul>
				</div>
			</div>
		

		<div class="switch-area">
			<div class="switch-wrap">
				<section class="switch-part switch-part1">
					<nav class="header-menu">
						<ul>
						
							<li><a href="/">主页</a></li>
				        
							<li><a href="/tags/life">随笔</a></li>
				        
							<li><a href="/archives">所有文章</a></li>
				        
						</ul>
					</nav>
					<nav class="header-nav">
						<div class="social">
							
								<a class="github" target="_blank" href="https://github.com/ruixiaoguo" title="github">github</a>
					        
								<a class="weibo" target="_blank" href="https://weibo.com/u/3984935859?refer_flag=1005055010_" title="weibo">weibo</a>
					        
								<a class="rss" target="_blank" href="#" title="rss">rss</a>
					        
								<a class="zhihu" target="_blank" href="#" title="zhihu">zhihu</a>
					        
						</div>
					</nav>
				</section>
				
				
				<section class="switch-part switch-part2">
					<div class="widget tagcloud" id="js-tagcloud">
						<a href="/tags/OC/" style="font-size: 10px;">-OC</a> <a href="/tags/Android/" style="font-size: 10px;">Android</a> <a href="/tags/Apple-Watch/" style="font-size: 10px;">Apple Watch</a> <a href="/tags/Flutter/" style="font-size: 13.33px;">Flutter</a> <a href="/tags/Life/" style="font-size: 10px;">Life</a> <a href="/tags/Lottie/" style="font-size: 10px;">Lottie</a> <a href="/tags/MMKV/" style="font-size: 10px;">MMKV</a> <a href="/tags/MonkeyKing/" style="font-size: 10px;">MonkeyKing</a> <a href="/tags/OC/" style="font-size: 20px;">OC</a> <a href="/tags/RAC/" style="font-size: 11.67px;">RAC</a> <a href="/tags/Swift/" style="font-size: 15px;">Swift</a> <a href="/tags/WKWebView/" style="font-size: 10px;">WKWebView</a> <a href="/tags/WebView/" style="font-size: 10px;">WebView</a> <a href="/tags/Xcode/" style="font-size: 18.33px;">Xcode</a> <a href="/tags/appledoc/" style="font-size: 10px;">appledoc</a> <a href="/tags/hexo/" style="font-size: 11.67px;">hexo</a> <a href="/tags/ios/" style="font-size: 10px;">ios</a> <a href="/tags/life/" style="font-size: 16.67px;">life</a> <a href="/tags/xcode/" style="font-size: 10px;">xcode</a>
					</div>
				</section>
				
				
				
				<section class="switch-part switch-part3">
					<div id="js-friends">
					
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.devtang.com">唐巧的博客</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://beyondvincent.com">破船之家</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://limboy.me">无网不剩</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://msching.github.io">码农人生</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://yulingtianxia.com">玉令天下</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.leichunfeng.com">雷纯锋的技术博客</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://jax.cnblogs.com">包建强</a>
			        
			          <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.cnbang.net">bang</a>
			        
			        </div>
				</section>
				

				
				
				<section class="switch-part switch-part4">
				
					<div id="js-aboutme">知识管理，时间管理，自我管理，阅读，语音写作，思维导图，Wiz，TimeMeter</div>
				</section>
				
			</div>
		</div>
	</header>				
</div>

    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
  	<div class="overlay">
  		<div class="slider-trigger"></div>
  		<h1 class="header-author js-mobile-header hide">Grx</h1>
  	</div>
	<div class="intrude-less">
		<header id="header" class="inner">
			<div class="profilepic">
			
				<img lazy-src="/img/rufei.jpg" class="js-avatar">
			
			</div>
			<hgroup>
			  <h1 class="header-author">Grx</h1>
			</hgroup>
			
			<p class="header-subtitle">自我管理，知识管理，时间管理，阅读，语音写作，思维导图</p>
			
			<nav class="header-menu">
				<ul>
				
					<li><a href="/">主页</a></li>
		        
					<li><a href="/tags/life">随笔</a></li>
		        
					<li><a href="/archives">所有文章</a></li>
		        
		        <div class="clearfix"></div>
				</ul>
			</nav>
			<nav class="header-nav">
				<div class="social">
					
						<a class="github" target="_blank" href="https://github.com/ruixiaoguo" title="github">github</a>
			        
						<a class="weibo" target="_blank" href="https://weibo.com/u/3984935859?refer_flag=1005055010_" title="weibo">weibo</a>
			        
						<a class="rss" target="_blank" href="#" title="rss">rss</a>
			        
						<a class="zhihu" target="_blank" href="#" title="zhihu">zhihu</a>
			        
				</div>
			</nav>
		</header>				
	</div>
</nav>

      <div class="body-wrap"><article id="post-程序员为什么热衷造轮子" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="/2015/08/17/程序员为什么热衷造轮子/" class="article-date">
  	<time datetime="2015-08-17T06:33:48.000Z" itemprop="datePublished">2015-08-17</time>
</a>
    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      程序员为什么热衷造轮子
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        
	<div class="article-tag tagcloud">
		<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/life/">life</a></li></ul>
	</div>

        

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="程序员为什么热衷造轮子"><a href="#程序员为什么热衷造轮子" class="headerlink" title="程序员为什么热衷造轮子"></a>程序员为什么热衷造轮子</h2><p> 搜索一下“造轮子”或者“程序员为什么喜欢造轮子”，会看到很多相关的讨论，这是个老生常谈的话题，很多人谈过了，谈了很多年。不过还是有再谈的必要。<br><a id="more"></a></p>
<h4 id="“造轮子”的含义："><a href="#“造轮子”的含义：" class="headerlink" title="“造轮子”的含义："></a>“造轮子”的含义：</h4><pre><code>明知道你做的不可能比前辈做得更好，却仍然坚持要做。
</code></pre><p>就软件开发而言，“造轮子”是指，“业界已经有公认的软件或者库了，却还坚持要自己做”。</p>
<p>在软件开发过程中，有时你想造轮子老板却极力反对，有时你不想造轮子老板却坚持要造一个出来，为什么会有这种两极状况？</p>
<p><br><br>这篇文章就来讨论“造轮子”这件事，包括下列主题：</p>
<ul>
<li>程序员为什么会重复造轮子</li>
<li>为什么有人不让“造轮子”</li>
<li>什么时候可以造轮子</li>
</ul>
<h4 id="为什么会重复造轮子？"><a href="#为什么会重复造轮子？" class="headerlink" title="为什么会重复造轮子？"></a>为什么会重复造轮子？</h4><p>每个造轮子的程序员都有自己“不得不造”的理由。比如：</p>
<ul>
<li>以为自己的需求独一无二，现有的库就是在某个点上满足不了</li>
<li>老轮子没有规格说明书，或者接口太复杂，不知道怎么用，搞明白太难</li>
<li>需要在老轮子上添加新功能，然而老轮子代码难读无人可问，不知道何时能弄明白，看不到结果，容易放弃</li>
<li>眼界有限，不知道已有这样的轮子</li>
<li>版权原因无法使用第三方库，比如Google Android实现JVM（Google曾因为一行代码而和Oracle打官司），比如阿里YunOS自己实现JVM</li>
<li>就想锻炼自己，因为造轮子对自己的设计、编码能力有很大好处，对理解业务也有很大好处</li>
<li>自己造轮子，有“控制感”，看得见摸的着，可以一步一步来，一个一个小目标迭代出大目标，不断成功的小激励，会带给自己前行的动力</li>
<li>创新成分多（对自己而言），有成就感</li>
<li>不相信老轮子，譬如老轮子可能有后门、漏洞（想想OpenSSL的心脏出血漏洞）、后期万一要修改没把握等，反正是觉得自己造轮子心里更踏实</li>
<li>不想让自己产品的关键技术掌握在别人手里，也不想让自己的核心用户数据流经别人的系统</li>
<li>别人的轮子不开放，我就是要赶紧造（山寨）一个出来以便获得话语权或商业利益</li>
</ul>
<hr>
<p>有坚持要造轮子的，也有高呼“不要重复造轮子”的。那为什么有人不让造轮子呢？</p>
<ul>
<li>项目（产品）时间紧张，用第三方库搭积木快，能节约时间</li>
<li>领导上（或队友）认为想造轮子的程序员水平就那样，不可能造出比现有库（软件）更好的轮子，显然会漏洞百出推高维护成本</li>
<li>造轮子是个看上去很美做起来很操蛋的事儿。复杂一点的轮子，造出来很费劲，道阻且长，很可能骑虎难下或半途而废，导致精力和时间的浪费</li>
<li>待造的轮子不是产品的关键（比如一个字符串类、一个XML解析类），不属于核心竞争力，不值得花费人力，要把精力放在最重要的事情上</li>
</ul>
<p>结合为什么要造轮子以及为什么不让造轮子，就可以理解本文一开始提到的那种反差极大的状况。</p>
<h4 id="什么样的轮子可以重新造？"><a href="#什么样的轮子可以重新造？" class="headerlink" title="什么样的轮子可以重新造？"></a>什么样的轮子可以重新造？</h4><p>看现在的软件发展趋势，越来越多的基础服务能够“开箱即用”、“拿来用就好”，越来越多的新软件可以通过组合已有类库、服务以搭积木的方式完成。这是趋势，将来不懂开发语言的人都可以通过利用现有软件组件快速构建出能解决实际问题的软件产品。</p>
<p><br><br>在这种趋势下，软件（服务）就慢慢演化为两极：</p>
<ul>
<li>满足终端用户的应用类产品</li>
<li>解决软件产品通用问题的基础服务（组件）</li>
</ul>
<p>比如你在自己的App中需要即时通信功能，完全可以使用融云、环信、网易云信等服务快速集成。</p>
<p>比如你想在自己的App中添加支付功能，完全可以使用Ping++或Pay++来解决诸多支付渠道的集成问题。</p>
<p>比如你想添加分享功能，ShareSDK、友盟SDK可以节省你很多时间。</p>
<p>比如你想做跨平台的游戏，使用Cocos2d-x远比自己在Android、iOS上从底层从OpenGL ES干起要高效得多。</p>
<p>比如你想让你的网站支持更多用户更多并发，能够快速部署、迁移、规模复制，那完全可以借助阿里云、AWS、Azure等而没必要自己搞。</p>
<p>比如你想推送消息给用户，就可以用腾讯信鸽、极光、个推、百度云推送、友盟等。</p>
<p>……</p>
<p>类似的场景很多很多。这种趋势使得一部分厂商集中精力开发基础服务（组件），一部分企业集中精力解决用户需求。对基础服务（组件）厂商来讲，他通过解决更复杂的基础问题为其他厂商带来便利而盈利。对终端软件产品企业来讲，他通过解决用户问题给用户创造价值而盈利，从理论上讲，只要其产品从用户端或第三方获取的价值大于支出给基础服务厂商的价值，生意就可以做下去。</p>
<p>有了这样的认识，什么样时候可以造轮子什么时候最好不重复造轮子就不再是问题了。</p>
<h4 id="对于提供基础服务的软件厂商，很多轮子必须造。"><a href="#对于提供基础服务的软件厂商，很多轮子必须造。" class="headerlink" title="对于提供基础服务的软件厂商，很多轮子必须造。"></a>对于提供基础服务的软件厂商，很多轮子必须造。</h4><p>因为他要提供服务给其他软件厂商，你拿友商的组件换个包装提供给其他软件厂商，没有竞争力。所以你看到在某个软件服务市场上，会有多家企业各自在造轮子，为的就是自己掌握核心科技有自己的竞争力。比如提供云服务的，有阿里，七牛，百度……比如提供即时通信服务的，有融云、环信、阿里云信……比如提供语音服务的，有科大讯飞、百度、OKVoice、Google、微软……</p>
<h4 id="对于开发满足终端用户的应用类产品的公司，很多轮子就没必要造"><a href="#对于开发满足终端用户的应用类产品的公司，很多轮子就没必要造" class="headerlink" title="对于开发满足终端用户的应用类产品的公司，很多轮子就没必要造"></a>对于开发满足终端用户的应用类产品的公司，很多轮子就没必要造</h4><p>比如你提供一个健身类的App，可能需要引入即时通信功能，用第三就好了。</p>
<p>从公司的角度讲是这个样子，那对程序员来讲呢？</p>
<h4 id="对程序员来讲，在一开始的学习成长阶段，造轮子则具有特殊的学习意义，学习别人怎么造，了解内部机理，自己造造看，这是非常好的锻炼。"><a href="#对程序员来讲，在一开始的学习成长阶段，造轮子则具有特殊的学习意义，学习别人怎么造，了解内部机理，自己造造看，这是非常好的锻炼。" class="headerlink" title="对程序员来讲，在一开始的学习成长阶段，造轮子则具有特殊的学习意义，学习别人怎么造，了解内部机理，自己造造看，这是非常好的锻炼。"></a>对程序员来讲，在一开始的学习成长阶段，造轮子则具有特殊的学习意义，学习别人怎么造，了解内部机理，自己造造看，这是非常好的锻炼。</h4><p>每次学习新技术都可以用这种方式来练习。</p>
<p>当我们掌握了一门技术，可以用于实际产品开发中时，关于造轮子，就有了另外的划分：</p>
<p>一些基础的工具类库，比如String，比如Xml，比如Json，比如Http，比如推送，比如流媒体协议，重新造的必要性不大。而与业务相关的，可以尝试重构、再造，对理解业务有好处，也能更好适应新需求。</p>
<hr>

      
    </div>
    
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2015/09/01/如何使用appledoc/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption"><</strong>
      <div class="article-nav-title">
        
          如何使用appledoc
        
      </div>
    </a>
  
  
    <a href="/2015/05/20/《重构》阅读笔记-代码的坏味道/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">《重构》阅读笔记-代码的坏味道</div>
      <strong class="article-nav-caption">></strong>
    </a>
  
</nav>

  
</article>


<div class="share_jia">
	<!-- JiaThis Button BEGIN -->
	<div class="jiathis_style">
		<span class="jiathis_txt">Share to: &nbsp; </span>
		<a class="jiathis_button_facebook"></a> 
    <a class="jiathis_button_twitter"></a>
    <a class="jiathis_button_plus"></a> 
    <a class="jiathis_button_tsina"></a>
		<a class="jiathis_button_cqq"></a>
		<a class="jiathis_button_douban"></a>
		<a class="jiathis_button_weixin"></a>
		<a class="jiathis_button_tumblr"></a>
    <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a>
	</div>
	<script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=1405949716054953" charset="utf-8"></script>
	<!-- JiaThis Button END -->
</div>






<div class="duoshuo">
	<!-- 多说评论框 start -->
	<div class="ds-thread" data-thread-key="程序员为什么热衷造轮子" data-title="程序员为什么热衷造轮子" data-url="http://yoursite.com/2015/08/17/程序员为什么热衷造轮子/"></div>
	<!-- 多说评论框 end -->
	<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
	<script type="text/javascript">
	var duoshuoQuery = {short_name:"true"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
	<!-- 多说公共JS代码 end -->
</div>




</div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info">
    	<div class="footer-left">
    		&copy; 2019 Grx
    	</div>
      	<div class="footer-right">
      		<a href="http://hexo.io/" target="_blank">Hexo</a>  Theme <a href="https://github.com/litten/hexo-theme-yilia" target="_blank">Yilia</a> by Litten
      	</div>
    </div>
  </div>
</footer>
    </div>
    
  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">


<script>
	var yiliaConfig = {
		fancybox: true,
		mathjax: true,
		animate: true,
		isHome: false,
		isPost: true,
		isArchive: false,
		isTag: false,
		isCategory: false,
		open_in_new: false
	}
</script>
<script src="http://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script src="/js/main.js"></script>






<script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
        processEscapes: true,
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    }
});

MathJax.Hub.Queue(function() {
    var all = MathJax.Hub.getAllJax(), i;
    for(i=0; i < all.length; i += 1) {
        all[i].SourceElement().parentNode.className += ' has-jax';                 
    }       
});
</script>

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  </div>
</body>
</html>